(function ($) {
    jsonp = function (url, success, error) {
        var option = init({
            url: url,
            success: success,
            dataType: 'jsonp',
            error: error
        });
        return request(option);
    };

    // jQuery.get
    httpGet = function (url, success, error) {
        var option = init({
            url: url,
            type: 'GET',
            success: success,
            error: error
        });
        return request(option);
    };

    // jQuery.post
    httpPost = function (url, data, success, error) {
        var option = init({
            url: url,
            data: data,
            success: success,
            error: error
        });
        return request(option);
    };

    // jQuery.ajax
    request = function (options) {
        return $.ajax(options);
    };

    /**
     * Ajax初始化参数
     * @param config
     */
    var init = function (config) {
        config = config || {};
        config.headers = config.headers || {};
        var ajaxConfig = {
            dataType: 'json',
            type: 'POST',
            data: {},
            cache: false,
            canonical: true,
            xhrFields: {
                withCredentials: true
            },
            headers: {
                'X-Data-Type': 'json',
                'X-Requested-With': 'XMLHttpRequest'
            },
            traditional: true,
            xhr: function () {
                var xhr = new XMLHttpRequest();
                xhr.upload.addEventListener("progress", function (evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = evt.loaded / evt.total;
                        if (config.progress) {
                            config.progress.call(this, parseInt(percentComplete * 100), percentComplete, evt);
                        }
                    }
                }, false);
                return xhr;
            }
        }


        $.extend(true, ajaxConfig, config);

        ajaxConfig.beforeSend = function (xhr) {
            if (config.beforeSend) {
                config.beforeSend.apply(this, arguments);
            }
        }

        ajaxConfig.success = function (data, status, jqXHR) {
            // 是否走标准流程
            if (ajaxConfig.canonical) {
                if (ajaxConfig.dataType.toLowerCase() === 'json' || ajaxConfig.dataType.toLowerCase() === 'jsonp') {
                    if (data && data.success) {
                        if (config.success)
                            config.success.apply(this, [data.data, data, config.content, status, jqXHR]);
                    } else {
                        if (codeHandler.call(codeHandler, data, config)) {
                        } else {
                            if (config.error) {
                                arguments[1] = 'error';
                                config.error.apply(this, arguments);
                            } else {
                                console.log(data.message);
                                console.log(data.code);
                            }
                        }
                    }
                } else {
                    config.success.apply(this, [data, config.content, status, jqXHR]);
                }
            } else {
                if (config.success) {
                    config.success.apply(this, [data, ajaxConfig.content, status, jqXHR]);
                }
            }
        }

        ajaxConfig.error = function (jqXHR, status, errorThrown) {
            jqXHR.message = status + ' 网络链接出错';
            if (config.error)
                config.error.apply(this, [jqXHR, status, errorThrown, config.content]);
            else
                console.log(status);
        }

        ajaxConfig.complete = function (jqXHR, status) {
            if (config.complete)
                config.complete.apply(this, [jqXHR, config.content, status]);
        }

        return ajaxConfig;
    };


    /**
     * 处理错误码
     * @param data
     * @param config
     * @returns {boolean}
     */
    var codeHandler = function (data, config) {
        data = data || {};
        if (data.code === 0) {
            return false;
        }
        if (data.data && typeof data.data === 'object') {
        }
        switch (data.code) {
            default:
                return false;
        }
        return true;
    }
})(jQuery);